/*
 * Created on Nov 27, 2005
 */
package dbsucxentW.pathProcessorW;

import java.sql.Connection;
import dbsucxentW.constantW.Constant;
import java.util.regex.*;
import java.sql.ResultSet;
import java.sql.Statement;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author Seah Boon Siew, modified by Lee Tzyy Ming & Klarinda
 */
public class Translator {

    String _xPath;
    String _fromSQL;
    String XPathErrMsg = "";
    boolean _updated;
    CurrentPath _currentPath;
    WhereSQL _whereSQL;
    Connection _dbConnection;
    boolean _singleDoc;
    boolean _showPath; // to include path of every leaf
    boolean _useTemp;
    int _depth;
    String _lastElement; // added by LTM
    // klarinda 20070426 - for hardcode RValue. If the beginning of XPath
    // contains "HARDCODE" -> mean hardcode RValue
    // ex: HARDCODE/a/b/c/d
    boolean _ishardcode = false;
    public int stepIndex = 1;
    public String[] pathString;
    public int _minDLevel = 0;
    // 20061206 no need; boolean _isFollowingOrPreceding = false; //for
    // following::QName or preceding::QName - klarinda 20061031
    boolean _isNewQuery = true;
    boolean _isWriteSQLToFile = false;

    public Translator(String xPath, Connection conn, boolean single, boolean showPath, boolean useTemp) {
        _xPath = xPath;
        _fromSQL = "";
        _updated = false;
        _dbConnection = conn;
        _currentPath = new CurrentPath(_dbConnection);
        _singleDoc = single;
        _useTemp = useTemp;
        _showPath = showPath;
        _ishardcode = single;
        _whereSQL = new WhereSQL(_singleDoc, _showPath);
    }

    @SuppressWarnings(value = "unchecked")
    public String translate() throws NoSuchPathException {
        System.out.println("Translator.translate(), XPath: " + _xPath); // klarinda
        /* ------------------------------------------------
        Added by Erwin 25-Jul-2007
        To check if the given XPath is a well-formed XPath
        ------------------------------------------------- */
        if (!isXPathWellFormed(_xPath)) {
            throw new NoSuchPathException("\"" + _xPath + "\" is not a well-formed XPath!\n\r\n\rError message from XPath parser:\n\r" + XPathErrMsg);
        }

        /* ------------------------------------------------
        Added by Erwin 2007-Sep-04
        To rewrite some XPath
        - /a/b[position()>=1] is equal to /a/b
        - /a/b[position()<=last()] is equal to /a/b
        ------------------------------------------------- */
        if (_xPath.contains("[position()>=1]")) {
            _xPath = _xPath.replace("[position()>=1]", "");
        } else if (_xPath.contains("[position()<=last()]")) {
            _xPath = _xPath.replace("[position()<=last()]", "");
        }

        /* ------------------------------------------------
        Added by Erwin 25-Jul-2007
        To translate simple XPath
        E.g: /a/b/c/d, /a/(star)/c/d, /a/b/c/@d, //a/b/c, /a//b/(star)/c, /a//b/(star)/@c, //a/@*, /a/(star)/c/@*
        ------------------------------------------------- */
        if (!_xPath.contains("::") && !_xPath.contains("[") && !_xPath.contains("]")) {
            SimpleXPathTranslator xpathtranslator = new SimpleXPathTranslator(_dbConnection, _xPath);
            String _SQL = xpathtranslator.getTranslatedSQL(_showPath);

            if (_SQL.equals("ERROR")) {
                throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
            } else {
                if (_useTemp) {
                    _SQL = rewriteSQLUsingTempTable(_SQL, false);
                }
                return _SQL;
            }
        }

        /* ------------------------------------------------
        Added by Erwin 22-Oct-2007
        To split the XPath based on steps
        For example:
        - /a/b[title='TCP/IP']/c will be split into
        - ("", "a","b[title='TCP/IP']","c")
        Remark: This replaces Klarinda's code
        ------------------------------------------------- */

        int bracketCounter = 0;
        int prevPos = 0;
        ArrayList tempresult = new ArrayList();
        boolean quote = false;
        boolean doublequote = false;
        boolean stringliteral = false;
        for (int i = 0; i < _xPath.length(); i++) {
            if (!stringliteral) {
                if (_xPath.charAt(i) == '\'') {
                    quote = true;
                    stringliteral = true;
                } else if (_xPath.charAt(i) == '"') {
                    doublequote = true;
                    stringliteral = true;
                }
            } else {
                if (quote && _xPath.charAt(i) == '\'') {
                    quote = false;
                    stringliteral = false;
                } else if (doublequote && _xPath.charAt(i) == '"') {
                    doublequote = false;
                    stringliteral = false;
                }
            }
            if ((_xPath.charAt(i) == '"') && (!stringliteral)) {
                quote = true;
            }
            if ((_xPath.charAt(i) == '[') && (!stringliteral)) {
                bracketCounter++;
            } else if ((_xPath.charAt(i) == ']') && (!stringliteral)) {
                bracketCounter--;
            }

            if ((_xPath.charAt(i) == '/') && (bracketCounter == 0)) {
                tempresult.add(_xPath.substring(prevPos, i));
                System.out.println(_xPath.substring(prevPos, i));
                prevPos = i + 1;
            }
        }
        tempresult.add(_xPath.substring(prevPos));
        String[] result = (String[]) tempresult.toArray(new String [tempresult.size ()]);


        /*    // Given an XPath, do a string manipulation to get each step, then call
        // processStep for each step
        // for example: /a/b[c/d = 'TCP/IP']/e is separated into: a, b[c/d =
        // 'TCP/IP'], e
        // (ideally W3C XPath parser should be used)
        String[] tempresult = _xPath.split("/");
        // separate XPath according
        // to "/"
        // To handle "/" in the middle of the string (klarinda 20061114)
        // ex: /a/b[title='TCP/IP Illustrated'] --> split("/") will return
        // "title='TCP" & "IP Illustrated'"
        // so need to combine "title='TCP" + "/" + "IP Illustrated'"
        int tempresult_length = tempresult.length;
        boolean quote = false;
        boolean doublequote = false;
        boolean stringliteral = false; // 20061123
        for (int p = 0; p < tempresult_length; p++) {
        quote = false;
        doublequote = false;
        stringliteral = false;
        // System.out.println(p+": "+tempresult[p]);
        for (int q = 0; q < tempresult[p].length(); q++) {
        if (!stringliteral) {
        if (tempresult[p].charAt(q) == '\'') {
        quote = true;
        stringliteral = true;
        } else if (tempresult[p].charAt(q) == '"') {
        doublequote = true;
        stringliteral = true;
        }
        } else {
        if (quote && tempresult[p].charAt(q) == '\'') {
        quote = false;
        stringliteral = false;
        } else if (doublequote && tempresult[p].charAt(q) == '"') {
        doublequote = false;
        stringliteral = false;
        }
        }
        }
        if (stringliteral) {
        tempresult_length--;
        tempresult[p] += "/" + tempresult[p + 1];
        // System.out.println(p+": After concat: "+tempresult[p]);
        for (int r = p + 1; r < tempresult_length; r++) {
        tempresult[r] = tempresult[r + 1]; // shift left operation
        }
        }
        }
        // To handle predicate with > 1 steps, ex: /bib/book[author/last =
        // 'Stevens'] (k 20061120)
        boolean openbracket = false;
        for (int p = 0; p < tempresult_length; p++) {
        // System.out.println(p+": "+tempresult[p]);
        for (int q = 0; q < tempresult[p].length(); q++) {
        if (tempresult[p].charAt(q) == '[') {
        openbracket = true;
        } else if (tempresult[p].charAt(q) == ']') {
        openbracket = false;
        }
        }
        if (openbracket) {
        tempresult_length--;
        tempresult[p] += "/" + tempresult[p + 1];
        // System.out.println(p+": After concat: "+tempresult[p]);
        for (int r = p + 1; r < tempresult_length; r++) {
        tempresult[r] = tempresult[r + 1]; // shift left operation
        }
        p--; // continue loop until found closebracket
        // (openbracket=false)
        }
        }
        // create a new array for the result
        String[] result = new String[tempresult_length];
        for (int p = 0; p < tempresult_length; p++) {
        result[p] = tempresult[p];
        }
         */

        // klarinda 20070426 for hardcode rvalue
        // if (result[0].trim().equals("HARDCODE")) { --> what is it?
        // added by erwin 2007-09-04
        // if there is ancestor/descendant axes, set _isharcode = false;
        if (_xPath.contains("ancestor::") || _xPath.contains("descendant::") || _xPath.contains("ancestor-or-self::") || _xPath.contains("descendant-or-self::")) {
            System.out.println("Translator.translate() HARDCODE");
            _ishardcode = false;
            _whereSQL.sethardcode(_ishardcode, _dbConnection);
        } else if (_singleDoc) {
            // added by erwin 2007-07-06
            System.out.println("Translator.translate() HARDCODE");
            _ishardcode = true;
            _whereSQL.sethardcode(_ishardcode, _dbConnection);
        }
        _isNewQuery = true;
        for (int x = 1; x < result.length; x++) {
            result[x] = result[x].trim(); // trim leading and trailing space
            System.out.println("\n\nTranslator.translate(), result[" + x + "] = " + result[x]); // klarinda 20060629
            pathString = result; // added by wang geng
            stepIndex = x; // added by wang geng
            if (x == result.length - 1) {
                // if the last step
                processStep(result[x], false, true);
                _depth = _currentPath.getLevel();
                _lastElement = result[x];
            } else {
                // if not the last step
                processStep(result[x], false, false);
            }
        }

        // join with Path table to obtain paths
        if (_showPath) {
            _whereSQL.addPaths();
        }
        String _SQL = _whereSQL.get();

        if (_useTemp) {
            _SQL = rewriteSQLUsingTempTable(_SQL, _whereSQL.getTables() == 1 ? true : false);
        }

        if (_isWriteSQLToFile) {
            try {
                BufferedWriter out = new BufferedWriter(new FileWriter("c:/SQL-Query.sql", true));
                out.write("XPath = " + _xPath + "\n\r");
                out.write("SQL Query\n\r");
                out.write(_SQL + "\n\r");
                out.write("-------------------------------------------\n\r\n\r");
                out.close();
            } catch (IOException e) {
            }
        }
        return _SQL;
    }
    // added by erwin

    private String rewriteSQLUsingTempTable(String input, boolean isSingleTable) {
        String _NewSQL = "";

        _NewSQL = input;

        if (input.contains("FROM Attribute A, V") && input.contains("UNION ALL")) {
            _NewSQL = _NewSQL.replace("WITH V", "INSERT INTO PVTemp");
            _NewSQL = _NewSQL.replace("AS (", "");
            if (isSingleTable) {
                _NewSQL = _NewSQL.replace(")  SELECT", "; \n SELECT");
                _NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
            } else {
                _NewSQL = _NewSQL.replace(")  SELECT", "OPTION (FORCE ORDER); \n SELECT");
                _NewSQL = _NewSQL.replace(") SELECT", "OPTION (FORCE ORDER); \n SELECT");
            }
            _NewSQL = _NewSQL.replace("FROM V", "FROM PVTemp V");
            _NewSQL = _NewSQL.replace("FROM Attribute A, V", "FROM Attribute A, PVTemp V");
        } else if (input.contains("FROM V, Attribute A") && input.contains("UNION ALL")) {
            _NewSQL = _NewSQL.replace("WITH V", "INSERT INTO PVTemp");
            _NewSQL = _NewSQL.replace("AS (", "");
            _NewSQL = _NewSQL.replace(")  SELECT", "; \n SELECT");
            _NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
            _NewSQL = _NewSQL.replace("FROM V", "FROM PVTemp V");
            _NewSQL = _NewSQL.replace("FROM Attribute A, V", "FROM Attribute A, PVTemp V");
        }

        return _NewSQL;
    }

    // added by LTM
    public int getDepth() {
        return _depth;
    }

    // added by LTM
    public String getLastElement() {
        return _lastElement;
    }

    // klarinda 20061206
    // given an XPath step, return the Step class (Step class contains the
    // summary for each step)
    // this class contains some string manipulation
    // ideally W3C XPath Parser should be used
    private Step getStep(String splice) throws NoSuchPathException {
        String axis;
        String nameTest = null;
        String predicates = null;
        String[] predicate = {" "};
        String[] equalityOperator = null;
        String[] equality = null;
        boolean hasPredicate = false;
        boolean[] hasEquality = {false};

        // split axis and predicate
        String[] parts = splice.split("::");

        // axis default?
        if (parts.length == 1) {
            // klarinda 20061103 add if @ -> attribute
            if (parts[0].length() == 0) {

                axis = "descendant";
            } else if (parts[0].charAt(0) == '@') {
                axis = "attribute";
            } else {
                axis = "child";
            }
            predicates = parts[0];
        } else if (parts.length == 2) {
            axis = parts[0];
            predicates = parts[1];
        } else {
            throw new NoSuchPathException("Too many axis, axis undetermined");
        }

        System.out.println("Translator.getStep(), axis=" + axis + ", predicates=" + predicates);
        // split predicate into nameTest and position based predicate(if any)
        int x = predicates.indexOf("[");
        int y = predicates.lastIndexOf("]");
        String[] parts2 = null;
        if (x >= 0) {
            parts2 = new String[2];
            parts2[0] = predicates.substring(0, x);
            parts2[1] = predicates.substring(x + 1, y);
        } else {
            parts2 = new String[1];
            parts2[0] = predicates;
        }

        //String[] parts2 = predicates.split("[\\[\\]]");
        for (int k = 0; k < parts2.length; k++) {
            // klarinda 20060629
            System.out.println("Translator.getStep(), parts2[" + k + "]=" + parts2[k]); // klarinda 20060629
            parts2[k] = parts2[k].trim();
        }

        // klarinda 20061122 string manipulation to separate based on "and",
        // "or", "(", or ")"
        // for example, the predicate: [title="abc" and ( ( publisher='xyz' and
        // price>400) or position()= 2 to 4 )]
        // i and or ( "expr" )
        // 0 false false 0 "title="abc"" 0
        // 1 true false 2 "publisher='xyz'" 0
        // 2 true false 0 "price>400" 1
        // 3 false true 0 "position()= 2 to 4" 1
        String[] expr = new String[20]; // assume 20 is max
        int[] noOfOpenParenthesis = new int[20];
        int[] noOfCloseParenthesis = new int[20];
        boolean[] andExpr = new boolean[20];
        boolean[] orExpr = new boolean[20];

        int state = 1;
        int pos = 0;
        int begin = pos;
        int exprIndex = 0;
        boolean quote = false;
        boolean doublequote = false;
        boolean stringliteral = false;
        boolean functioncall = false;
        String pred = "";

        if (parts2.length == 2) {
            // changed by erwin
            pred = parts2[1];
        } else if (parts2.length > 2) {
            for (int i = parts2.length - 2; i > 1; i--) {
            }
        }
        while (pos < pred.length()) {
            if (state == 1) {
                if (pred.charAt(pos) == ' ') {
                } else if (pred.charAt(pos) == '(') {
                    noOfOpenParenthesis[exprIndex]++;
                } else {
                    state++; // go to the next state
                    quote = false;
                    doublequote = false; // initialization for the next state
                    stringliteral = false;
                    functioncall = false;
                    begin = pos;
                    pos--; // need to minus because the pos will be incremented
                }
            } else if (state == 2) {
                if (!stringliteral) {
                    if (pred.charAt(pos) == '\'') {
                        quote = true;
                        stringliteral = true;
                    } else if (pred.charAt(pos) == '"') {
                        doublequote = true;
                        stringliteral = true;
                    } else if (pred.charAt(pos) == '(') {
                        functioncall = true;
                    } else if (pred.charAt(pos) == ')' && functioncall) {
                        functioncall = false;
                    } else if (pred.charAt(pos) == ')' && !functioncall) {
                        expr[exprIndex] = pred.substring(begin, pos).trim();
                        exprIndex++;
                        state++;
                        pos--;
                    } else if (pos == pred.length() - 1) {
                        expr[exprIndex] = pred.substring(begin, pos + 1).trim();
                        exprIndex++;
                    } else if (pos + 5 < pred.length() && pred.substring(pos, pos + 5).compareTo(" and ") == 0) {
                        expr[exprIndex] = pred.substring(begin, pos).trim();
                        exprIndex++;
                        andExpr[exprIndex] = true;
                        pos = pos + 4;
                        state = 1;
                    } else if (pos + 4 < pred.length() && pred.substring(pos, pos + 4).compareTo(" or ") == 0) {
                        expr[exprIndex] = pred.substring(begin, pos).trim();
                        exprIndex++;
                        orExpr[exprIndex] = true;
                        pos = pos + 3;
                        state = 1;
                    }
                } else {
                    if (quote && pred.charAt(pos) == '\'') {
                        quote = false;
                        stringliteral = false;
                        if (pos == pred.length() - 1) {
                            expr[exprIndex] = pred.substring(begin, pos + 1).trim();
                            exprIndex++;
                        }
                    } else if (doublequote && pred.charAt(pos) == '"') {
                        doublequote = false;
                        stringliteral = false;
                        if (pos == pred.length() - 1) {
                            expr[exprIndex] = pred.substring(begin, pos + 1).trim();
                            exprIndex++;
                        }
                    }
                }
            } else if (state == 3) {
                if (pred.charAt(pos) == ' ') {
                } else if (pred.charAt(pos) == ')') {
                    noOfCloseParenthesis[exprIndex - 1]++;
                } else {
                    state++; // go to the next state
                    pos--;
                }
            } else if (state == 4) {
                if (pred.substring(pos, pos + 3).compareTo("and") == 0) {
                    andExpr[exprIndex] = true;
                    pos++;
                    pos++;
                } else if (pred.substring(pos, pos + 2).compareTo("or") == 0) {
                    orExpr[exprIndex] = true;
                    pos++;
                }
                state = 1;
                System.out.println("\nstate 4 -> state 1");
            } else {
                throw new NoSuchPathException("Invalid state!");
            }
            pos++;
        }
        System.out.println("\ni and or ( Expr )");
        for (int i = 0; i < exprIndex; i++) {
            System.out.println(i + " " + andExpr[i] + " " + orExpr[i] + " " + noOfOpenParenthesis[i] + " \"" + expr[i] + "\" " + noOfCloseParenthesis[i]);
        }
        System.out.println("\n");


        if (parts2.length == 1) {
            nameTest = parts2[0];
            String[] temp = {" "};
            predicate = temp;
            hasPredicate = false;
        } else if (parts2.length == 2) {
            // changed by erwin
            nameTest = parts2[0];
            // predicate = parts2[1];
            hasPredicate = true;

            if (exprIndex == 0 && parts2[1].endsWith("last()")) {
                exprIndex++;
                expr[0] = parts2[1];
            }

            // actually the name predicate supposed to be changed to expression.
            // but there are too many parts need to be changed because of this.
            // so i just keep the original
            predicate = new String[exprIndex];
            for (int i = 0; i < exprIndex; i++) {
                predicate[i] = expr[i];
            }
            equality = new String[predicate.length];
            hasEquality = new boolean[predicate.length];
            equalityOperator = new String[predicate.length];

            for (int i = 0; i < predicate.length; i++) {
                hasEquality[i] = false;
                equalityOperator[i] = "";
                equality[i] = "";

                String[] equalityParts = predicate[i].split("!=");
                if (equalityParts.length > 1) {
                    equalityOperator[i] = "!=";
                    predicate[i] = equalityParts[0];
                    equality[i] = equalityParts[1];
                    hasEquality[i] = true;
                } else {
                    equalityParts = predicate[i].split("<=");
                }
                if (equalityParts.length > 1 && !hasEquality[i]) {
                    if (equalityParts[0].trim().equals("position()")) {
                        System.out.println("position()");
                        predicate[i] = equalityParts[1].trim();
                        equalityOperator[i] = "<=";
                        equalityParts = predicate[i].split(">=");
                    } else {
                        equalityOperator[i] = "<=";
                        predicate[i] = equalityParts[0];
                        equality[i] = equalityParts[1];
                        hasEquality[i] = true;
                    }
                } else {
                    equalityParts = predicate[i].split(">=");
                }
                if (equalityParts.length > 1 && !hasEquality[i]) {
                    if (equalityParts[0].trim().equals("position()")) {
                        System.out.println("position()");
                        predicate[i] = equalityParts[1].trim();
                        equalityOperator[i] = ">=";
                        equalityParts = predicate[i].split("=");
                    } else {
                        equalityOperator[i] = ">=";
                        predicate[i] = equalityParts[0];
                        equality[i] = equalityParts[1];
                        hasEquality[i] = true;
                    }
                } else {
                    equalityParts = predicate[i].split("=");
                }
                if (equalityParts.length > 1 && !hasEquality[i]) {
                    if (equalityParts[0].trim().equals("position()")) {
                        System.out.println("position()");
                        predicate[i] = equalityParts[1].trim();
                        // added by erwin
                        equalityParts = predicate[i].split("<");
                    } else {
                        equalityOperator[i] = "=";
                        if (equalityParts.length > 2) {
                            equality[i] = equalityParts[equalityParts.length - 1];
                            predicate[i] = "";
                            for (int xx = equalityParts.length - 2; xx >= 0; xx--) {
                                if (xx != equalityParts.length - 2) {
                                    predicate[i] = equalityOperator[i] + predicate[i];
                                }
                                predicate[i] = equalityParts[xx] + predicate[i];
                            }
                        } else {
                            predicate[i] = equalityParts[0];
                            equality[i] = equalityParts[1];
                        }

                        // SQL can't accept ", can only accept '
                        // SQL need to escape ', ex: Smith's --> Smith''s
                        String temp = equalityParts[equalityParts.length - 1].trim();
                        if (temp.charAt(0) == '\'' || temp.charAt(0) == '"') {
                            equality[i] = "'" + temp.substring(1, temp.length() - 1).replaceAll("'", "''") + "'";
                        } else {
                            equality[i] = temp;
                        }
                        hasEquality[i] = true;
                    }
                } else {
                    equalityParts = predicate[i].split("<");
                }
                if (equalityParts.length > 1 && !hasEquality[i]) {
                    if (equalityParts[0].trim().equals("position()")) {
                        System.out.println("position()");
                        predicate[i] = equalityParts[1].trim();

                        hasEquality[i] = predicate[i].contains("last()") == true ? false : true;

                        equalityOperator[i] = "<";
                        equalityParts = predicate[i].split(">");
                    } else {
                        equalityOperator[i] = "<";
                        predicate[i] = equalityParts[0];
                        equality[i] = equalityParts[1];
                        hasEquality[i] = true;
                    }
                } else {
                    equalityParts = predicate[i].split(">");
                }
                if (equalityParts.length > 1 && !hasEquality[i]) {
                    if (equalityParts[0].trim().equals("position()")) {
                        System.out.println("position()");
                        predicate[i] = equalityParts[1].trim();
                        equalityOperator[i] = ">";
                    } else {
                        equalityOperator[i] = ">";
                        predicate[i] = equalityParts[0];
                        equality[i] = equalityParts[1];
                        hasEquality[i] = true;
                    }
                } else if (equalityParts.length == 1 && equalityParts[0].equals(predicate[i]) && equalityOperator[i].length() == 0) {
                    Pattern pat = Pattern.compile("([0-9])+ (TO) ([0-9])+");
                    Matcher mat = pat.matcher(predicate[i].toUpperCase());
                    if (mat.matches()) {
                    } else if (predicate[i].contains("last()")) {
                        predicate[i] = equalityParts[0];
                        hasEquality[i] = false;
                    } else if (!isNumber(predicate[i])) {
                        equalityOperator[i] = "!!!";
                        predicate[i] = equalityParts[0];
                        hasEquality[i] = true;
                    }
                }
                predicate[i] = predicate[i].trim();
            }
        }


        System.out.println("Translator.getStep(), createStep");
        System.out.println("   axis          : " + axis);
        System.out.println("   nameTest      : " + nameTest);
        System.out.print("   predicate     : ");
        if (predicate != null) {
            for (int k = 0; k < predicate.length; k++) {
                System.out.print(predicate[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   equality      : ");
        if (equality != null) {
            for (int k = 0; k < equality.length; k++) {
                System.out.print(equality[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.println("   hasPredicate  : " + hasPredicate);
        System.out.print("   hasEquality   : ");
        if (hasEquality != null) {
            for (int k = 0; k < hasEquality.length; k++) {
                System.out.print(hasEquality[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   equalityOp    : ");
        if (equalityOperator != null) {
            for (int k = 0; k < equalityOperator.length; k++) {
                System.out.print(equalityOperator[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   no of (       : ");
        if (predicate != null) {
            for (int k = 0; k < predicate.length; k++) {
                System.out.print(noOfOpenParenthesis[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   no of )       : ");
        if (predicate != null) {
            for (int k = 0; k < predicate.length; k++) {
                System.out.print(noOfCloseParenthesis[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   andExpr       : ");
        if (predicate != null) {
            for (int k = 0; k < predicate.length; k++) {
                System.out.print(andExpr[k] + ", ");
            }
        }
        System.out.print("\n");
        System.out.print("   or Expr       : ");
        if (predicate != null) {
            for (int k = 0; k < predicate.length; k++) {
                System.out.print(orExpr[k] + ", ");
            }
        }
        System.out.print("\n");

        Step step = new Step(axis, nameTest, predicate, equality, hasPredicate, hasEquality, equalityOperator, noOfOpenParenthesis, noOfCloseParenthesis, andExpr, orExpr);
        return step;
    }

    /*
     * process each step first step: processStep(result[x],true,false); -->
     * always ignore 1st step others : processStep(result[x],false,false); last
     * step : processStep(result[x],false,true);
     */
    void processStep(String splice, boolean first, boolean last) throws NoSuchPathException {
        System.out.println("Translator.processStep(" + splice + "," + first + "," + last + ")"); // klarinda 20060629
        // added by erwin to handle /a/b[x=1][y=2]
        if (splice.contains("][")) {
            String[] temp = splice.split("[\\[\\]]");
            String newPred = "[";
            for (int i = 1; i < temp.length; i += 2) {
                Pattern p = Pattern.compile("(\\[(position\\(\\)(>|<|(<=)|(>=)|=))?(([0-9])+( (to) ([0-9])+)?|(last\\(\\))((-)([0-9])+)?)\\])");
                Matcher m = p.matcher("[" + temp[i] + "]");
                if (m.matches()) {
                    if (newPred.length() == 1) {
                        newPred += temp[i] + "]";
                    } else {
                        newPred += "][" + temp[i];
                    }
                } else {
                    if (newPred.length() == 1) {
                        newPred += temp[i];
                    } else {
                        newPred += " and " + temp[i];
                    }
                }
            }
            newPred += "]";
            splice = temp[0] + newPred;
        }

        Step step = getStep(splice); // 20061206 separate the string manipulation part to another function
        if ((step.getAxis().compareTo("child") == 0) && (step.hasPredicate() == false)) {
            _currentPath.add(step.getNameTest());
            _updated = true;
            _depth++;
        } else if (step.getAxis().compareTo("self") == 0) {
            System.out.println("Translator.processStep(), axis = self"); // klarinda
            if (_whereSQL.getTables() == 0) {
                _whereSQL.newTable();
            }
            String lastStep = _currentPath.getLastStep();
            String inpath = "";
            String inpathAttr = "";

            // wild card needs to return the principal node kind of the step
            // axis
            // For example, child::* will select all element children of the
            // context node (doesn't include attribute or text node)
            // node() matches any node
            // child::node() selects all the children of the context node; no
            // attribute nodes are returned, b'cos attributes are not children
            if (lastStep.compareTo("*") == 0) {
                inpath = _currentPath.getPathExcludeAttrText(false);
                inpathAttr = _currentPath.getPathExcludeAttrText(true);
            } else if (lastStep.compareTo("node()") == 0) {
                inpath = _currentPath.getPathExcludeAttr(false);
                inpathAttr = _currentPath.getPathExcludeAttr(true);
            } else {
                inpath = _currentPath.getPath(false);
                inpathAttr = _currentPath.getPath(true);
            }

            if (inpath.equals("()")) {
                throw new NoSuchPathException("The path does not exist");
            }
            _whereSQL.add("VK.pathid in " + inpath, false);
            _whereSQL.setAttributePath(inpathAttr); // klarinda 20060908
            // (separate Attribute
            // table)
            if (step.hasPredicate() == false) {
                _currentPath.removeLast();
                _currentPath.add(step.getNameTest());
                _updated = true;
            } else {
                _currentPath.removeLast(); // klarinda 20061208
                _currentPath.add(step.getNameTest()); // klarinda 20061208
                _whereSQL.newRv(_currentPath.getLevel()); // klarinda 20061208
                // (because the newRV from processPredicate is removed)
                processPredicate(step);
            }
        } else if (step.getAxis().compareTo("attribute") == 0) {
            if (!last) {
                throw new NoSuchPathException("Attribute axis should be the last step");
            }
            _currentPath.add(step.getNameTest());
            String inpathAttr = _currentPath.getPath(true);
            _whereSQL.setAttributePath(inpathAttr);
            _updated = false;
        } else {
            // To check if there is position predicate
            // added by E.L 22-Oct-2007
            boolean _curStepHasEquality = true;
            boolean[] temp = step.hasEquality();
            for (int x = 0; x < temp.length; x++) {
                if (!temp[x]) {
                    _curStepHasEquality = false;
                    break;
                }
            }

            // update to SQL
            if (_updated == true && _currentPath.getLevel() > 1 && !_curStepHasEquality) {
                if (_whereSQL.getTables() == 0) {
                    _whereSQL.newTable();
                }
                String inpath = "";
                String inpathAttr = "";

                inpath = _currentPath.getPath(false);
                inpathAttr = _currentPath.getPath(true);

                if (inpath.equals("()")) {
                    throw new NoSuchPathException("The path does not exist");
                }
                _whereSQL.add("VK.pathid in " + inpath, false);
                _whereSQL.setAttributePath(inpathAttr); // klarinda 20060908
                _updated = false;
            }

            if (_currentPath.getLevel() > 1 && !_curStepHasEquality) {
                if (_whereSQL.getTables() == 0) {
                    _whereSQL.newTable(); // } fix added by LTM
                }
                int j = _currentPath.getLevel();
                if (_currentPath.getPathString().indexOf("%") < 0) {
                    // for descendant step, branchOrder can not be determined
                    // ---Wang  Geng
                    _whereSQL.add("VK.branchOrder < " + j, false); // to get the
                    // context nodes (represented by 1st desc leaf node)
                }
            }

            // process axis
            processAxis(step);
            // process predicate
            if (step.hasPredicate()) {
                processPredicate(step);
            }
        }

        if (step.getAxis().compareTo("attribute") == 0) {
            if (!last) {
                throw new NoSuchPathException("Attribute axis should be the last step");
            }
            _whereSQL.setonlyReturnAttribute(true);
            _whereSQL.setAttributePath(_currentPath.getPath(true));
            _updated = false;
        }

        // last step finalization (update path to SQL if not updated)
        if (last && _updated == true) {
            System.out.println("Translator.processStep(), last && updated==true");
            if (_whereSQL.getTables() == 0) {
                _whereSQL.newTable();
            }

            String inpath = "";
            String inpathAttr = "";

            // wild card needs to return the principal node kind of the step axis
            // For example, child::* will select all element children of the
            // context node (doesn't include attribute or text node)
            // node() matches any node
            // child::node() selects all the children of the context node; no
            // attribute nodes are returned, b'cos attributes are not children
            if (step.getNameTest().compareTo("*") == 0) {
                inpath = _currentPath.getPathExcludeAttrText(false);
                inpathAttr = _currentPath.getPathExcludeAttrText(true);
            } else if (step.getNameTest().compareTo("node()") == 0) {
                inpath = _currentPath.getPathExcludeAttr(false);
                inpathAttr = _currentPath.getPathExcludeAttr(true);
            } else {
                inpath = _currentPath.getPath(false);
                inpathAttr = _currentPath.getPath(true);
            }

            if (inpath.equals("()")) {
                throw new NoSuchPathException("The path does not exist");
            }
            _whereSQL.add("VK.pathid in " + inpath, false);
            _whereSQL.setAttributePath(inpathAttr);
        }
    }

    void processChildAxis(Step step) {
        System.out.println("Translator.processAxis(), step: CHILD");
        int j = _currentPath.getLevel() - 1;
        if (_currentPath.getLevel() > 1) {
            int noTables = _whereSQL.getTables();
            _whereSQL.newRv(_currentPath.getLevel());
            _whereSQL.newRv(_currentPath.getLevel() + 1);
            _whereSQL.newTable();

            // j will always be greater than zero
            if (noTables > 0) {
                if (j > 0) {
                    // theorem 1
                    _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT) - 1 ", false);
                } else {
                    _whereSQL.add("VK.DeweyOrderSum >= 0", false);
                }
            }
        } else {
            _whereSQL.newRv(_currentPath.getLevel() + 1);
            _whereSQL.newTable();

            // never reachable
            if (_currentPath.getLevel() > 1) {
                _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", false);
            }
        }
        _currentPath.add(step.getNameTest()); // klarinda 20061205 (move inside if-else)
    }

    void processFollowingAxis(Step step) {
        System.out.println("Translator.processAxis(), step: FOLLOWING");
        _whereSQL.setDistinct(true);
        int j = _currentPath.getLevel();
        _whereSQL.newRv(j);
        _whereSQL.newTable();
        _whereSQL.setAttributePath("");
        _currentPath.clearPath(); // klarinda 20060912 to facilitate nametest after fol / prec
        _currentPath.add("*"); // klarinda 20060912 to facilitate nametest after fol / prec
        if (step.getNameTest().compareTo("*") == 0 && step.getNameTest().compareTo("node()") == 0) {
            _whereSQL.add("VK.DeweyOrderSum >=  VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1  ", false);
        } else {
            int k = _currentPath.getQNameLevel_setCurrentPath(step.getNameTest()); // level from root to QName
            if (k >= j) {
                _whereSQL.add("VK.DeweyOrderSum >=  VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1  ", false);
            } else {
                _whereSQL.newRv(k);
                _whereSQL.add("VK.DeweyOrderSum >=  VL.DeweyOrderSum + 2 * CAST(RL.RValue as BIGINT) - 1  " + "+ CAST(RK.RValue as BIGINT) - 1 ", false);
            }
        }
    }

    void processPrecedingAxis(Step step) {
        System.out.println("Translator.processAxis(), step: PRECEDING");
        _whereSQL.setDistinct(true);
        int j = _currentPath.getLevel();
        _whereSQL.newTable();
        _whereSQL.setAttributePath("");
        _currentPath.clearPath(); // klarinda 20060912 to facilitate nametest after fol / prec
        _currentPath.add("*"); // klarinda 20060912 to facilitate nametest after fol / prec
        if (step.getNameTest().compareTo("*") == 0 && step.getNameTest().compareTo("node()") == 0) {
            _whereSQL.add("VK.DeweyOrderSum <  VL.DeweyOrderSum ", false);
        } else {
            int k = _currentPath.getQNameLevel_setCurrentPath(step.getNameTest()); // level from root to QName
            if (k >= j) {
                _whereSQL.add("VK.DeweyOrderSum <  VL.DeweyOrderSum ", false);
            } else {
                // since QName level (k) < context node level (j),
                // so need to exclude the nodes which has common ancestor at
                // QName level using theorem 1
                _whereSQL.newRv(k);
                _whereSQL.add("VK.DeweyOrderSum <  VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1 ", false);
            }
        }
    }

    void processFollowingSiblingAxis(Step step) {
        System.out.println("Translator.processAxis(), step: FOLLOWING_SIBLING");
        _whereSQL.setDistinct(true);
        _whereSQL.newRv(_currentPath.getLevel() - 1);
        _whereSQL.newRv(_currentPath.getLevel());
        _whereSQL.newTable();
        int j = _currentPath.getLevel() - 1;

        if (j > 1 && _whereSQL.getTables() > 0) {
            _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1" + "\n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT) - 1 ", false);
        } else if (j < 1) {
            _whereSQL.add("VK.DeweyOrderSum < 0", false);
        } else {
            _whereSQL.add("VK.DeweyOrderSum >= VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1", false);
        }
        _currentPath.removeLast();
        _currentPath.add(step.getNameTest());
    }

    void processPrecedingSiblingAxis(Step step) {
        System.out.println("Translator.processAxis(), step: PRECEDING_SIBLING");
        _whereSQL.setDistinct(true);
        _whereSQL.newRv(_currentPath.getLevel() - 1);
        _whereSQL.newRv(_currentPath.getLevel());
        _whereSQL.newTable();

        int j = _currentPath.getLevel() - 1;

        if (j > 1) {
            _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT)  + 1" + "\n\t\t AND VL.DeweyOrderSum  - 1  ", false);
        } else {
            // klarinda 20060629 - add else
            _whereSQL.add("VK.DeweyOrderSum < VL.DeweyOrderSum ", false);
        }
        _currentPath.removeLast();
        _currentPath.add(step.getNameTest());
    }

    void processAxis(Step step) throws NoSuchPathException {
        System.out.println("Translator.processAxis()");
        int type = step.getType();
        if (type == Constant.CHILD) {
            processChildAxis(step);
        } else if (type == Constant.FOLLOWING) {
            processFollowingAxis(step);
        } else if (type == Constant.PRECEDING) {
            processPrecedingAxis(step);
        } else if (type == Constant.FOLLOWING_SIBLING) {
            processFollowingSiblingAxis(step);
        } else if (type == Constant.PRECEDING_SIBLING) {
            processPrecedingSiblingAxis(step);
        } else if (type == Constant.ATTRIBUTE) {
            System.out.println("Translator.processAxis(), step: ATTRIBUTE");
        } else if (type == Constant.PARENT) {
            // parent --> note implemented yet
            System.out.println("Translator.processAxis(), step: PARENT");
            _currentPath.removeLast();
            _currentPath.removeLast();
            if (step.getNameTest().compareTo("*") == 0 || step.getNameTest().compareTo("node()") == 0) {
                _currentPath.add(step.getNameTest());
            }
            _whereSQL.setDistinct(true);
            _whereSQL.newRv(_currentPath.getLevel());
            _whereSQL.newRv(_currentPath.getLevel() + 1);
            _whereSQL.newTable();

            if (_currentPath.getLevel() > 0) {
                _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT)  + 1" + "\n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT)  - 1", false);
            } else {
                throw new NoSuchPathException("Parent axis incorrect");
            }
        } else if (type == Constant.SELF) {
            System.out.println("Translator.processAxis(), step: SELF");
        } else if (type == Constant.ANCESTOR || type == Constant.ANCESTOR_OR_SELF) {
            // ancestor
            _whereSQL._ancestorIndex++;

            _whereSQL.newTable();

            _whereSQL.newATable(_whereSQL._ancestorIndex);

            _whereSQL.add("A" + _whereSQL._ancestorIndex + ".AncestorId=" + _whereSQL._ancestorIndex, false);

            if (_whereSQL._ADMonitor == -1) {
                // last AD step is ancestor
                if (type == Constant.ANCESTOR_OR_SELF) {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
                } else {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
                }
                _whereSQL.add("VL.BranchOrder<A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
            } else if (_whereSQL._ADMonitor == 1) {
                // last AD step is
                // descendant
                if (type == Constant.ANCESTOR_OR_SELF) {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
                } else {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
                }
                _whereSQL.add("VL.BranchOrder<D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
            } else {
                // no ancestor or descendant before
                if (type == Constant.ANCESTOR_OR_SELF) {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=" + _currentPath.getLevel(), false);
                } else {
                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<" + _currentPath.getLevel(), false);
                }
            }

            _whereSQL.add("VK.pathid=A" + _whereSQL._ancestorIndex + ".pathid", false);

            _whereSQL.newRv("A" + _whereSQL._ancestorIndex + ".level-1");

            _whereSQL.add("VL.DeweyOrdersum<=(SELECT Min(VTmp.deweyordersum) from PathValue as VTmp where VTmp.PathId=VL.PathId AND VTmp.DocId=VL.DocId AND ABS(VTmp.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,VL.DocId)) < CAST(RK.RValue as BIGINT))", false);
            _whereSQL.add("ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) < CAST(RK.RValue as BIGINT)", false);
            if (_whereSQL._ADMonitor == -1) {
                int tempIndex = _whereSQL._ancestorIndex - 1;
                _whereSQL.newRv("A" + tempIndex + ".level-3+" + _currentPath.getLevel());
            }

            if (_whereSQL._ADMonitor == 1) {
                _whereSQL.newRv("D" + _whereSQL._descendantIndex + ".level-1+" + _currentPath.getLevel());
            }
            if (_whereSQL._ADMonitor == 0) {
                _whereSQL.newRv(_currentPath.getLevel() + "-1");
            }

            _whereSQL.add("(ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) > CAST(RK.RValue as BIGINT) OR ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) < 3)", false);

            try {
                Statement statement = _dbConnection.createStatement();
                Statement statement2 = _dbConnection.createStatement();
                String sqlquery;
                if (_isNewQuery) {
                    sqlquery = "TRUNCATE TABLE AncestorTemp ";
                    statement.execute(sqlquery);
                    _isNewQuery = false;
                }

                if (_whereSQL._ancestorIndex == 1) {
                    sqlquery = "DELETE FROM AncestorTemp WHERE NOT Level<0";
                    statement.execute(sqlquery);
                }

                String tempCurrentStepNameTest = "." + step.getNameTest() + "#";
                stepIndex++;
                while (stepIndex < pathString.length) {
                    Step tempStep = getStep(pathString[stepIndex]);
                    if (tempStep.hasPredicate() || tempStep.getType() != Constant.CHILD) {
                        break;
                    }
                    tempCurrentStepNameTest = tempCurrentStepNameTest + "." + tempStep.getNameTest() + "#";
                    stepIndex++;
                }

                sqlquery = "SELECT PathExp,PathId FROM Path WHERE PATHEXP LIKE '%" + tempCurrentStepNameTest + "%'";
                ResultSet results = statement.executeQuery(sqlquery);
                int count;
                while (results.next()) {
                    System.out.println("****test**** PathId=" + results.getString("PathId"));
                    count = 0;
                    String pathExpTemp = results.getString("PathExp");

                    while (pathExpTemp.indexOf(tempCurrentStepNameTest) >= 0) {

                        String tempString = pathExpTemp;

                        pathExpTemp = pathExpTemp.substring(0, pathExpTemp.indexOf(tempCurrentStepNameTest)) + "." + step.getNameTest() + "#";

                        for (int i = 0; i < pathExpTemp.length(); i++) {
                            if (pathExpTemp.charAt(i) == '.') {
                                count++;
                            }
                        }

                        sqlquery = "INSERT INTO AncestorTemp (PathId,AncestorId,Level,AnceBranchOrd) VALUES (" + results.getString("PathId") + "," + _whereSQL._ancestorIndex + "," + count + ",0)";
                        statement2.execute(sqlquery);
                        pathExpTemp = tempString.substring(pathExpTemp.length(), tempString.length());
                    }
                }

                sqlquery = "SELECT ALL P.PathId AS PathId,P.PathExp AS PathExp,A.Level AS Level FROM Path AS P,AncestorTemp AS A WHERE P.PathId=A.PathId AND A.AncestorId=" + (_whereSQL._ancestorIndex) + "ORDER BY P.PathId";
                ResultSet resultPathExp = statement.executeQuery(sqlquery);
                resultPathExp.next();

                String prePathExp = resultPathExp.getString("PathExp");
                System.out.println("****test**** PrePathExp = " + prePathExp);
                String currentPathExp;
                while (resultPathExp.next()) {
                    currentPathExp = resultPathExp.getString("PathExp");
                    System.out.println("****test**** PrePathExp = " + prePathExp);
                    System.out.println("****test**** currentPathExp = " + currentPathExp);
                    String[] tempPathExp1 = prePathExp.split("\\.");
                    String[] tempPathExp2 = currentPathExp.split("\\.");
                    int i = 1;
                    while (i < tempPathExp1.length && tempPathExp1[i].trim().indexOf(tempPathExp2[i].trim()) == 0) {
                        i++;
                        System.out.println("****test**** i = " + i);
                    }
                    i--;
                    System.out.println("****test**** i = " + i);
                    sqlquery = "UPDATE AncestorTemp SET AnceBranchOrd=" + i + " WHERE AncestorId=" + (_whereSQL._ancestorIndex) + " AND PathId=" + resultPathExp.getString("PathId") + " AND Level=" + resultPathExp.getString("Level");
                    statement2.execute(sqlquery);
                    prePathExp = currentPathExp;
                }

                if (_whereSQL._ADMonitor == 1) {

                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level>D" + (_whereSQL._descendantIndex) + ".DescBranchOrd", false);
                }
                if (_whereSQL._ADMonitor == -1) {

                    _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level>A" + (_whereSQL._ancestorIndex - 1) + ".AnceBranchOrd", false);
                }
            } catch (Exception ex) {
            }
            _currentPath.clearPath();
            _currentPath.add("*");
            _currentPath.add(step.getNameTest());
            _whereSQL._ADMonitor = -1;
        } else if (type == Constant.ANCESTOR_OR_SELF) { // ancestor-or-self
        } else if (type == Constant.DESCENDANT || type == Constant.DESCENDANT_OR_SELF) {
            // descendant
            if (type == Constant.DESCENDANT_OR_SELF) {
                String[] partsTemp = _currentPath.getPathString().split("\\.");
                String TempNameTest = partsTemp[partsTemp.length - 1].substring(0, partsTemp[partsTemp.length - 1].length() - 1);

                if (TempNameTest.indexOf("%") == 0) {
                    TempNameTest = TempNameTest.substring(1, TempNameTest.length());
                }
                if (TempNameTest.compareTo(step.getNameTest()) == 0) {
                    _currentPath.removeLast();
                }
                System.out.println("Translator.processAxis(), step: DESCENDANT-OR-SELF");
            } else {

                System.out.println("Translator.processAxis(), step: DESCENDANT");
            }

            if (_currentPath.getLevel() > 1) {
                _whereSQL.newRv(_currentPath.getLevel());
            } else {
                _whereSQL.newRv(_currentPath.getLevel() + 1);
            }

            if (_whereSQL._ADMonitor == 1) {
                _whereSQL.add("D" + _whereSQL._descendantIndex + ".Level<=D" + (_whereSQL._descendantIndex + 1) + ".Level", false);
                _whereSQL.add("VK.BranchOrder<RK.Level+1", false);
            }
            if (_whereSQL._ADMonitor == -1) {
                _whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<D" + (_whereSQL._descendantIndex + 1) + ".Level+1+" + _currentPath.getLevel(), false);
                _whereSQL.add("VK.BranchOrder<RK.Level+1", false);
            }

            _whereSQL._descendantIndex++;

            _whereSQL.newTable();

            if (_currentPath.getLevel() > 1) {
                _whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum " + " \n\t\t AND VL.DeweyOrderSum + 2*CAST(RK.RValue as BIGINT) - 2 ", false);
            }

            _currentPath.addForDescendantAxis(step.getNameTest()); // change by erwin
            String tempCurrentPath;
            tempCurrentPath = _currentPath.getPathString();

            String tempCurrentStepNameTest = "." + step.getNameTest() + "#";
            stepIndex++;

            while (stepIndex < pathString.length) {
                Step tempStep = getStep(pathString[stepIndex]);
                if (tempStep.hasPredicate() || tempStep.getType() != Constant.CHILD) {
                    break;
                }
                _currentPath.add(tempStep.getNameTest());
                tempCurrentStepNameTest = tempCurrentStepNameTest + "." + tempStep.getNameTest() + "#";
                stepIndex++;
            }

            System.out.println("****test**** changed currentPath= " + _currentPath.getPathString());
            System.out.println("****test**** temp current step= " + tempCurrentStepNameTest);

            String inpath;
            inpath = _currentPath.getPath(false);
            inpath = inpath.substring(1, inpath.length() - 1);

            _currentPath.setCurrentPathString(tempCurrentPath);

            System.out.println("****test**** inpath= " + inpath);
            String[] inpathId = inpath.split(",");
            try {
                Statement statement = _dbConnection.createStatement();
                Statement statement2 = _dbConnection.createStatement();
                int tempIndex = 0;
                String[] tempPathExpStepArr;
                String tempStepPathExp;
                String sqlquery;
                int tempLevel;

                if (_isNewQuery) {
                    sqlquery = "TRUNCATE TABLE DescendantTemp ";
                    statement.execute(sqlquery);
                    _isNewQuery = false;
                }

                if (_whereSQL._descendantIndex == 1) {
                    sqlquery = "DELETE FROM DescendantTemp WHERE NOT Level<0";
                    statement.execute(sqlquery);
                }
                String[] tempStepCurrentPath;

                if (_whereSQL._ADMonitor == -1) {
                    tempStepCurrentPath = _currentPath.getPathString().substring(3, _currentPath.getPathString().length()).split("\\.");
                } else {
                    tempStepCurrentPath = _currentPath.getPathString().split("\\.");
                }

                for (int i = 1; i < tempStepCurrentPath.length - 1; i++) {

                    if (tempStepCurrentPath[i].indexOf("%") == 0) {
                        tempStepCurrentPath[i] = tempStepCurrentPath[i].substring(1, tempStepCurrentPath[i].indexOf("#"));
                    } else {
                        tempStepCurrentPath[i] = tempStepCurrentPath[i].substring(0, tempStepCurrentPath[i].indexOf("#"));
                    }
                }

                for (int i = 0; i < inpathId.length; i++) {
                    System.out.println("****test**** inpathId[" + i + "]= " + inpathId[i]);
                    String tempPathExp;
                    sqlquery = "SELECT PathExp FROM Path WHERE PathId=" + inpathId[i];
                    ResultSet results = statement.executeQuery(sqlquery);
                    results.next();
                    tempPathExp = results.getString("PathExp");
                    System.out.println("****test**** tempPathExp= " + tempPathExp);

                    for (int i2 = 1; i2 < tempStepCurrentPath.length - 1; i2++) {
                        tempIndex = tempPathExp.indexOf("." + tempStepCurrentPath[i2] + "#", tempIndex);
                        tempIndex++;
                    }
                    tempIndex += tempStepCurrentPath[tempStepCurrentPath.length - 2].length();

                    int minLevel = -1;

                    while (tempPathExp.indexOf(tempCurrentStepNameTest, tempIndex) > tempIndex) {
                        System.out.println("****test**** entered while loop ");
                        tempIndex = tempPathExp.indexOf(tempCurrentStepNameTest, tempIndex);
                        System.out.println("****test**** tempIndex= " + tempIndex);
                        tempStepPathExp = tempPathExp.substring(0, tempIndex) + "." + step.getNameTest() + "#";
                        System.out.println("****test**** tempStepPathExp = " + tempStepPathExp);
                        tempPathExpStepArr = tempStepPathExp.split("\\.");

                        tempLevel = tempPathExpStepArr.length - 1 - _currentPath.getLevel();
                        if (tempLevel < minLevel || minLevel == -1) {
                            minLevel = tempLevel;
                        }
                        System.out.println("****test**** tempLevel = " + tempLevel);
                        sqlquery = "INSERT INTO DescendantTemp (PathId,DescendantId,Level,DescBranchOrd) VALUES (" + inpathId[i] + "," + _whereSQL._descendantIndex + "," + tempLevel + ",0)";
                        statement.execute(sqlquery);

                        tempIndex++;
                    }
                    tempIndex = 0;
                    _minDLevel = minLevel;
                }

                sqlquery = "SELECT ALL P.PathId AS PathId,P.PathExp AS PathExp,D.Level AS Level FROM Path AS P,DescendantTemp AS D WHERE P.PathId=D.PathId AND D.DescendantId=" + _whereSQL._descendantIndex + "ORDER BY P.PathId";
                ResultSet resultPathExp = statement.executeQuery(sqlquery);
                resultPathExp.next();

                String prePathExp = resultPathExp.getString("PathExp");
                System.out.println("****test**** PrePathExp = " + prePathExp);
                String currentPathExp;
                while (resultPathExp.next()) {
                    currentPathExp = resultPathExp.getString("PathExp");
                    System.out.println("****test**** currentPathExp = " + currentPathExp);
                    String[] tempPathExp1 = prePathExp.split("\\.");
                    String[] tempPathExp2 = currentPathExp.split("\\.");
                    int i = 1;
                    while (i < tempPathExp1.length && tempPathExp1[i].trim().indexOf(tempPathExp2[i].trim()) == 0) {
                        i++;
                        System.out.println("****test**** i = " + i);
                    }
                    i--;
                    System.out.println("****test**** i = " + i);
                    sqlquery = "UPDATE DescendantTemp SET DescBranchOrd=" + i + " WHERE DescendantId=" + _whereSQL._descendantIndex + " AND PathId=" + resultPathExp.getString("PathId") + " AND Level=" + resultPathExp.getString("Level");
                    statement2.execute(sqlquery);
                    prePathExp = currentPathExp;
                }
            } catch (Exception ex) {
            }

            _whereSQL.newDTable(_whereSQL._descendantIndex);

            _whereSQL.add("D" + _whereSQL._descendantIndex + ".PathId=VK.PathId", false);
            _whereSQL.add("D" + _whereSQL._descendantIndex + ".DescendantId=" + _whereSQL._descendantIndex, false);

            _whereSQL._ADMonitor = 1;
        } else if (type == Constant.DESCENDANT_OR_SELF) { // descendant-or-self
        } else {
            throw new NoSuchPathException("Path axis incorrect");
        }
        _updated = true;
    }

    void processPredicate(Step step) throws NoSuchPathException {
        int n_from = 0;
        int n_to = 0;
        int nf;
        int nt;
        int noOfEquality = 0; // k
        boolean additionalPred = false;
        String additionalPredStr = "";
        System.out.println("Translator.processPredicate()"); // klarinda
        for (int i = 0; i < step.getPredicate().length; i++) {
            if (step.hasEquality(i)) {
                noOfEquality++; // count how many tables need to be added
            }
        }
        // new table only needed if the predicate is not position based predicate
        _whereSQL.setNoOfNewTables(noOfEquality); // klarinda 20061123
        _whereSQL.setDistinct(true);
        for (int i = 0; i < step.getPredicate().length; i++) {
            if (step.hasEquality(i)) {
                CurrentPath tempPath = new CurrentPath(_dbConnection);
                tempPath.addString(_currentPath.getPathString());
                // for predicate > 1 steps (klarinda 20061120)
                String[] predicateStep = step.getPredicate(i).split("/");
                for (int x = 0; x < predicateStep.length; x++) {
                    if (!predicateStep[x].trim().equals("text()")) {
                        if ((predicateStep[x].trim().contains("[")) && (predicateStep[x].trim().contains("]"))) {
                            Pattern p = Pattern.compile("([@a-zA-Z_0-9])+(\\[(position\\(\\)(>|<|(<=)|(>=)|=))?(([0-9])+( (to) ([0-9])+)?|(last\\(\\))((-)([0-9])+)?)\\])?");
                            Matcher m = p.matcher(predicateStep[x].trim());
                            if (m.matches()) {
                                additionalPred = true;
                                additionalPredStr = predicateStep[x].trim().substring(predicateStep[x].trim().indexOf("[") + 1, predicateStep[x].trim().lastIndexOf("]"));
                                predicateStep[x] = predicateStep[x].trim().substring(0, predicateStep[x].trim().indexOf("["));
                                tempPath.add(predicateStep[x].trim());
                            } else {
                                throw new NoSuchPathException("Currently, XCalibur does not support your XPath!");
                            }
                        } else {
                            tempPath.add(predicateStep[x].trim());
                        }
                    }
                }

                _whereSQL.newTable();
                if (step.getEquality(i).trim().length() > 0) {
                    if ((step.getEquality(i).trim().charAt(0) == '"') && (step.getEquality(i).trim().charAt(step.getEquality(i).trim().length() - 1) == '"')) {
                        step.setEquality(i, step.getEquality(i).trim().replaceAll("\"", "'"));
                    }
                }
                boolean isJoin = false;
                // if ((step.getEqualityOperator(i).equals("=") || step.getEqualityOperator(i).equals("!=")) && step.getEquality(i).charAt(0) != '\'') {
                if (step.getEquality(i).charAt(0) != '\'') {
                    try {
                        Float.valueOf(step.getEquality(i));
                    } catch (NumberFormatException e) {
                        isJoin = true;
                        boolean isSlash = (step.getEquality(i).charAt(0) == '/') ? true : false;
                        boolean isJoinAttribute = false;

                        CurrentPath joinPath = new CurrentPath(_dbConnection);
                        if (!isSlash) {
                            joinPath.addString(_currentPath.getPathString());
                        }
                        String[] joinStep = step.getEquality(i).split("/");
                        for (int x = 0; x < joinStep.length; x++) {
                            joinPath.add(joinStep[x].trim());
                        }

                        isJoinAttribute = (joinStep[joinStep.length - 1].trim().charAt(0) == '@') ? true : false;
                        String joinPathId = joinPath.getOnePath();
                        if (joinPathId.equals("()")) {
                            throw new NoSuchPathException("The join path does not exist");
                        }
                        String joinValue;
                        if (isJoinAttribute) {
                            // attribute table is separated from elements
                            _whereSQL.newJoinAttributeTable();
                            _whereSQL.add("ALj.pathid in " + joinPathId, true); // j is for join
                            joinValue = " ALj.leafValue ";
                            if (!isSlash) {
                                _whereSQL.newJoinTable();
                                _whereSQL.add(" ALj.docId = VL.docId \n AND VLj.leafOrder = ALj.LeafOrder ", true);
                            }
                        } else {
                            _whereSQL.newJoinTable(); // the order of table in
                            // fromSQL is not so correct (ignore this prob for time being)
                            _whereSQL.add("VLj.pathid in " + joinPathId, true); // j is for join
                            joinValue = " VLj.leafValue ";
                        }

                        String joinNotSlash = "";
                        if (!isSlash) {
                            joinNotSlash = "\n\tAND VK.DeweyOrderSum BETWEEN VLj.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VLj.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ";
                        }

                        if (step.getPredicate(i).charAt(0) == '@') {
                            // attribute, need to join with attribute table
                            _whereSQL.newAttributeTable();
                            _whereSQL.add("AL.LeafOrder = VL.LeafOrder ", true);
                            if (step.getEqualityOperator(i).equals("=")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue like " + joinValue + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue like " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue not like  " + joinValue + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue not like  " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            }
                        } else {
                            if (step.getEqualityOperator(i).equals("=")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue like " + joinValue + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue like " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS  \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else if (step.getEqualityOperator(i).equals("=")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue not like " + joinValue + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue not like " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else if (step.getEqualityOperator(i).equals(">")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) > CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) > CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else if (step.getEqualityOperator(i).equals(">=")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) >= CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) >= CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else if (step.getEqualityOperator(i).equals("<")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) < CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) < CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            } else if (step.getEqualityOperator(i).equals("<=")) {
                                // added by erwin
                                Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                                Matcher mat = pat.matcher(joinValue);
                                if (mat.matches()) {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) <= CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                } else {
                                    _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) <= CAST(" + joinValue + " as FLOAT) \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
                                }
                            }                          
                            
                        }
                    }
                }

                if (!isJoin) {
                    // klarinda 20070613: NOT JOIN
                    // klarinda 20070108 to fix OR
                    // _whereSQL.addPredicate("VK.DeweyOrderSum BETWEEN
                    // VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" +
                    // " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT)
                    // - 1 " );
                    // klarinda 200060901 attribute table is separated from
                    // elements
                    // if (step.getPredicate(i).charAt(0) == '@') { //
                    // attribute,
                    if (step.getPredicate(i).indexOf("@") >= 0) {
                        // added bby erwin 2007-08-02
                        // -> for /a/b[c/@id] need to join with attribute table
                        _whereSQL.newAttributeTable();
                        _whereSQL.add("AL.LeafOrder = VL.LeafOrder ", true);
                        if (step.getEqualityOperator(i).equals("=")) {
                            // added by erwin
                            Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                            Matcher mat = pat.matcher(step.getEquality(i));
                            if (mat.matches()) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue like " + step.getEquality(i) + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            } else {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue like " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            }
                        } else if (step.getEqualityOperator(i).equals("!=")) {
                            Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
                            Matcher mat = pat.matcher(step.getEquality(i));
                            if (mat.matches()) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue not like " + step.getEquality(i) + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            } else {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.leafValue not like " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            }
                        } else if (step.getEqualityOperator(i).equals("!!!")) {
                            // added by erwin
                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "\n\t VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                        } else {
                            try {
                                Float temp = Float.valueOf(step.getEquality(i));
                                if (temp == null) {
                                    throw new NoSuchPathException("Predicate value incorrect");
                                }
                            } catch (NumberFormatException e) {
                                throw new NoSuchPathException("Precicate value incorrect");
                            }
                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(AL.leafValue as FLOAT) " + step.getEqualityOperator(i) + " " + step.getEquality(i) + "\n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                        }
                    } else {
                        // For MINT query only
                        if (step.getEqualityOperator(i).equals("!!!")) {
                            _whereSQL.addAndOrExprMINT(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                        } else if (step.getEqualityOperator(i).equals("=")) {
                            Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
                            Matcher mat = pat.matcher(step.getEquality(i));
                            if (mat.matches()) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue like " + step.getEquality(i) + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            } else {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue like " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            }
                        } else if (step.getEqualityOperator(i).equals("!=")) {
                            Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
                            Matcher mat = pat.matcher(step.getEquality(i));
                            if (mat.matches()) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue not like " + step.getEquality(i) + " \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            } else {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.leafValue not like " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                            }
                        } else {
                            try {
                                Float temp = Float.valueOf(step.getEquality(i));
                                if (temp == null) {
                                    throw new NoSuchPathException("Predicate value incorrect");
                                }
                            } catch (NumberFormatException e) {
                                throw new NoSuchPathException("Precicate value incorrect");
                            }
                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.leafValue as FLOAT) " + step.getEqualityOperator(i) + " " + step.getEquality(i) + "\n\tAND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
                        }
                    }
                }
                String inpath = tempPath.getOnePath();

                // klarinda 20070108 for MINT query only
                if (step.getEqualityOperator(i).equals("!!!")) {
                    if (step.getPredicate(i).indexOf("@") < 0) {
                        inpath = tempPath.getPath(false);
                    }
                }

                // end of klarinda 20070108
                if (inpath.equals("()")) {
                    throw new NoSuchPathException("The path does not exist");
                }

                if (step.getPredicate(i).indexOf("@") >= 0) {
                    // added bby erwin
                    // 2007-08-02 -> for /a/b[c/@id]
                    _whereSQL.add("AL.pathid in " + inpath, true);
                } else {
                    _whereSQL.add("VL.pathid in " + inpath, true);
                }
                // klarinda 20070108 for MINT query only
                if (step.getEqualityOperator(i).equals("!!!")) {
                    // to get the context nodes (represented by 1st desc leaf node)
                    _whereSQL.add("VL.branchOrder < " + tempPath.getLevel(), false);
                }
                System.out.println("PP:" + tempPath.getPathString());
            } else {
                switch (step.getType()) {
                    case Constant.CHILD:
                        n_from = step.getPredicateFrom(i);
                        n_to = step.getPredicateTo(i);
                        break;
                    case Constant.FOLLOWING:
                        n_from = step.getPredicateFrom(i) + 1;
                        n_to = step.getPredicateTo(i) + 1;
                        break;
                    case Constant.PRECEDING:
                        n_from = -step.getPredicateFrom(i) + 1;
                        n_to = -step.getPredicateTo(i) + 1;
                        break;
                    case Constant.FOLLOWING_SIBLING:
                        n_from = step.getPredicateFrom(i) + 1;
                        n_to = step.getPredicateTo(i) + 1;
                        break;
                    case Constant.PRECEDING_SIBLING:
                        n_from = -step.getPredicateFrom(i) + 1;
                        n_to = -step.getPredicateTo(i) + 1;
                        break;
                    case Constant.SELF:
                        n_from = step.getPredicateFrom(i);
                        n_to = step.getPredicateTo(i);
                        break;
                    default:
                        System.out.println("ERROR:Axis type cannot have predicate\n"); // ???
                }

                switch (step.getPredicateType()) {
                    case 0:
                        // position based predicate without name test
                        nf = n_from - 1;
                        nt = n_to;
                        if (step.getPredicate(i).startsWith("last()")) {
                            String inpathAttr = _currentPath.getPath(false);

                            int c = _whereSQL.getLastTempTableCounter();
                            String additionExp2 = step.getPredicate(i).replace("last()", "");
                            String additionExp1 = "(L" + (c + 1) + ".MAXI " + additionExp2 + " - 1 )";
                            String myQuery = "";
                            try {
                                Statement stmt = _dbConnection.createStatement();
                                if (c == 0) {
                                    stmt.executeUpdate("TRUNCATE TABLE  [LASTTEMP] ");

                                    if (_currentPath.getLevel() == 2) {
                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + (c + 1) + " AS FLAG, " + "0 AS DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PATHID IN " + inpathAttr + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 1 OR BRANCHORDER = 0) ";
                                        System.out.println(myQuery);
                                        System.out.println("------");
                                        stmt.executeUpdate(myQuery);
                                    } else {
                                        String parentPath = _currentPath.getPrevPath(false);
                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + "0 AS FLAG, " + "DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PATHID IN " + parentPath + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 2 OR BRANCHORDER = 0) ";
                                        System.out.println(myQuery);
                                        System.out.println("------");
                                        stmt.executeUpdate(myQuery);

                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT " + "  ROW_NUMBER() OVER(PARTITION BY P.DOCID,L.DEWEYORDERSUM ORDER BY P.DOCID, P.DEWEYORDERSUM) AS RID, " + "  P.DOCID, P.SIBLINGSUM, 1 AS FLAG, P.DEWEYORDERSUM, L.DEWEYORDERSUM  AS PDOS " + "FROM LASTTEMP AS L, PATHVALUE AS P, DocumentRValue R " + "WHERE L.DOCID = P.DOCID " + "  AND L.DOCID = R.DOCID " + "  AND L.FLAG = 0 " + "  AND R.LEVEL = " + (_currentPath.getLevel() - 2) + " " + "  AND P.PATHID IN " + inpathAttr + " " + "  AND P.BRANCHORDER < " + _currentPath.getLevel() + " " + "  AND P.DeweyOrderSum BETWEEN L.DeweyOrderSum - CAST(R.RValue as BIGINT) + 1 " + "                          AND L.DeweyOrderSum + CAST(R.RValue as BIGINT) - 1" + "  AND  P.SiblingSum >= L.SiblingSum ";

                                        System.out.println(myQuery);
                                        System.out.println("------");
                                        stmt.executeUpdate(myQuery);
                                    }
                                } else {
                                    // multi last predicate
                                }
                                stmt.close();
                            } catch (Exception e) {
                            }

                            _whereSQL.addLastTempTable(_currentPath.getLevel());

                            if (step.getEqualityOperator(i).equals("<")) {
                                additionExp1 = "0";
                                additionExp2 = "-1";
                            }
                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.DeweyOrderSum BETWEEN VM.DeweyOrderSum + " + additionExp1 + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.DeweyOrderSum + " + " (L" + (c + 1) + ".MAXI " + additionExp2 + " )" + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
                        } else {
                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VK.DeweyOrderSum BETWEEN VM.DeweyOrderSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) " + " \n\t\t AND VM.DeweyOrderSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
                        }
                        break;
                    case 1:
                        nf = n_from - 1;
                        nt = n_to;
                        // k20061123 change VL to VM
                        if (step.getPredicate(i).startsWith("last()")) {
                            String inpathAttr = _currentPath.getPath(false);

                            int c = _whereSQL.getLastTempTableCounter();
                            String additionExp2 = step.getPredicate(i).replace("last()", "");
                            String additionExp1 = "(L" + (c + 1) + ".MAXI " + additionExp2 + " - 1 )";

                            String myQuery = "";
                            try {
                                Statement stmt = _dbConnection.createStatement();
                                if (c == 0) {
                                    stmt.executeUpdate("TRUNCATE TABLE  [LASTTEMP] ");

                                    if (_currentPath.getLevel() == 2) {
                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + (c + 1) + " AS FLAG, " + "0 AS DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PATHID IN " + inpathAttr + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 1 OR BRANCHORDER = 0) ";

                                        stmt.executeUpdate(myQuery);
                                        System.out.println(myQuery);
                                        System.out.println("------");
                                    } else {

                                        String parentPath = _currentPath.getPrevPath(false);

                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + "0 AS FLAG, " + "DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PATHID IN " + parentPath + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 2 OR BRANCHORDER = 0) ";
                                        System.out.println(myQuery);
                                        System.out.println("------");
                                        stmt.executeUpdate(myQuery);


                                        myQuery = "INSERT INTO  [LASTTEMP]" + "SELECT " + "  ROW_NUMBER() OVER(PARTITION BY P.DOCID,L.DEWEYORDERSUM ORDER BY P.DOCID, P.DEWEYORDERSUM) AS RID, " + "  P.DOCID, P.SIBLINGSUM, 1 AS FLAG, P.DEWEYORDERSUM, L.DEWEYORDERSUM  AS PDOS " + "FROM LASTTEMP AS L, PATHVALUE AS P, DocumentRValue R " + "WHERE L.DOCID = P.DOCID " + "  AND L.DOCID = R.DOCID " + "  AND L.FLAG = 0 " + "  AND R.LEVEL = " + (_currentPath.getLevel() - 2) + " " + "  AND P.PATHID IN " + inpathAttr + " " + "  AND P.BRANCHORDER < " + _currentPath.getLevel() + " " + "  AND P.DeweyOrderSum BETWEEN L.DeweyOrderSum - CAST(R.RValue as BIGINT) + 1 " + "                          AND L.DeweyOrderSum + CAST(R.RValue as BIGINT) - 1" + "  AND  P.SiblingSum >= L.SiblingSum ";
                                        System.out.println(myQuery);
                                        System.out.println("------");
                                        stmt.executeUpdate(myQuery);
                                    }
                                } else {
                                    // multi last predicate
                                }
                                stmt.close();
                            } catch (Exception e) {
                            }
                            if (step.getEqualityOperator(i).equals("<")) {
                                additionExp1 = "0";
                                additionExp2 = "-1";
                            }
                            _whereSQL.addLastTempTable(_currentPath.getLevel());

                            _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum BETWEEN VM.SiblingSum + " + additionExp1 + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.SiblingSum + " + " (L" + (c + 1) + ".MAXI " + additionExp2 + " )" + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
                        } else {
                            if (nt == -1) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum > VM.SiblingSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1", step.getNoOfCloseParenthesis(i));
                            } else if (nf == -1) {
                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum < VM.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1", step.getNoOfCloseParenthesis(i));
                            } else {

                                _whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum BETWEEN VM.SiblingSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
                            }
                        }
                        break;
                    default:
                }
            }
        }

        if (additionalPred) {
            Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
            Matcher mat = pat.matcher(additionalPredStr);
            if (mat.matches()) {
                nf = Integer.parseInt(additionalPredStr) - 1;
                nt = Integer.parseInt(additionalPredStr);
                _whereSQL.newRv(_currentPath.getLevel() + 1);
                _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
            } else if (additionalPredStr.startsWith("position()")) {
                pat = Pattern.compile("([0-9])+ (TO) ([0-9])+");
                mat = pat.matcher(additionalPredStr.toUpperCase());
                if (mat.matches()) {
                    String[] toParts = additionalPredStr.toUpperCase().split("TO");
                    Integer castedInt = new Integer(toParts[0].trim());
                    nf = castedInt.intValue() - 1;
                    castedInt = new Integer(toParts[1].trim());
                    nt = castedInt.intValue();
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
                } else if (additionalPredStr.contains(">=")) {
                    String[] toParts = additionalPredStr.toUpperCase().split(">=");
                    Integer castedInt = new Integer(toParts[1].trim());
                    nt = -1;
                    nf = castedInt.intValue() - 1;
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum > 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1 ", 0);
                } else if (additionalPredStr.contains("<=")) {

                    String[] toParts = additionalPredStr.toUpperCase().split("<=");
                    Integer castedInt = new Integer(toParts[1].trim());
                    nf = 0;
                    nt = castedInt.intValue();
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
                } else if (additionalPredStr.contains(">")) {
                    String[] toParts = additionalPredStr.toUpperCase().split(">");
                    Integer castedInt = new Integer(toParts[1].trim());
                    nf = castedInt.intValue();
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum > 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1 ", 0);
                } else if (additionalPredStr.contains("<")) {
                    String[] toParts = additionalPredStr.toUpperCase().split("<");
                    Integer castedInt = new Integer(toParts[1].trim());
                    nt = castedInt.intValue() - 1;
                    nf = 0;
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
                } else if (additionalPredStr.contains("=")) {
                    String[] toParts = additionalPredStr.toUpperCase().split("=");
                    Integer castedInt = new Integer(toParts[1].trim());
                    nf = castedInt.intValue() - 1;
                    castedInt = new Integer(toParts[1].trim());
                    nt = castedInt.intValue();
                    _whereSQL.newRv(_currentPath.getLevel() + 1);
                    _whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VK.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
                }
            }
        }

        _whereSQL.endOfPredicate();
    }

    // add by erwin 2007-07-04
    private boolean isNumber(String s) {
        try {
            int I = Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return false;
        }
        return true;
    }

    // added by erwin 25-Jul-2007
    private boolean isXPathWellFormed(String XPath) {
        long t1 = System.currentTimeMillis();
        try {
            dbsucxentW.pathProcessorW.w3cxpathparserW.XPath parser = new dbsucxentW.pathProcessorW.w3cxpathparserW.XPath(new java.io.StringBufferInputStream(XPath));
            dbsucxentW.pathProcessorW.w3cxpathparserW.SimpleNode tree;
            tree = parser.XPath2();
            if (((dbsucxentW.pathProcessorW.w3cxpathparserW.SimpleNode) tree
					.jjtGetChild(0)).toString().equals("XPath")) {
                long t2 = System.currentTimeMillis();
                System.out.println("isXPathWellFormed: " + (t2 - t1) + " msec");
                return true;
            }
        } catch (dbsucxentW.pathProcessorW.w3cxpathparserW.ParseException pe) {
            XPathErrMsg = pe.getMessage();
        } catch (dbsucxentW.pathProcessorW.w3cxpathparserW.TokenMgrError tme) {
            XPathErrMsg = tme.getMessage();
        }
        long t2 = System.currentTimeMillis();

        System.out.println("isXPathWellFormed: " + (t2 - t1) + " msec");
        return false;
    }

    void ProcessChildAncestor(String[] OriginalPath, int arrIndex) {
        if (arrIndex < 3) {
            for (int i = 0; i < OriginalPath.length; i++) {
                OriginalPath[i] = "";
            }
        } else {
            OriginalPath[arrIndex] = OriginalPath[arrIndex].substring(0, 8) + "-or-self" + OriginalPath[arrIndex].substring(8);

            OriginalPath[arrIndex - 1] = "[child::" + OriginalPath[arrIndex - 1].substring(0, OriginalPath[arrIndex - 1].length()) + "]";

            OriginalPath[arrIndex - 2] = OriginalPath[arrIndex - 2] + OriginalPath[arrIndex - 1];

            OriginalPath[arrIndex - 1] = "";
        }
    }

    void ProcessSelfAncestor(String[] originalPath, int arrIndex) {
        if (arrIndex < 4) {
            for (int i = 0; i < originalPath.length; i++) {
                originalPath[i] = "";
            }
        } else {
            originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]";
            originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
            originalPath[arrIndex - 1] = "";
        }
    }

    void ProcessFollowingSiblingAncestor(String[] originalPath, int arrIndex) {
        if (arrIndex < 4) {
            for (int i = 0; i < originalPath.length; i++) {
                originalPath[i] = "";
            }
        } else {
            originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]";
            originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
            originalPath[arrIndex - 1] = "";
        }
    }

    void ProcessDescendantAncestor(String[] originalPath, int arrIndex) {
        if (arrIndex < 3) {
            for (int i = 0; i < originalPath.length; i++) {
                originalPath[i] = "";
            }
        } else {
            String tempOriginalPath = "[" + originalPath[arrIndex - 1] + "]";
            originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]/";

            for (int i = arrIndex; i < originalPath.length; i++) {
                originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + originalPath[i] + "/";
            }

            originalPath[arrIndex - 1] = originalPath[arrIndex - 1].substring(0, originalPath[arrIndex - 1].length() - 1);
            originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + "|";

            originalPath[arrIndex] = "/descendant-or-self" + originalPath[arrIndex].substring(originalPath[arrIndex].indexOf("::")) + tempOriginalPath;

            for (int i = arrIndex - 2; i > 0; i--) {
                originalPath[arrIndex] = "/" + originalPath[i] + originalPath[arrIndex];
            }

            originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
            originalPath[arrIndex - 1] = "";

            if (originalPath[arrIndex].indexOf("/") == 0) {
                originalPath[arrIndex] = originalPath[arrIndex].substring(1, originalPath[arrIndex].length());
            }
        }
    }

    void ProcessFollowingAncestor(String[] originalPath, int arrIndex) {
        if (arrIndex < 4) {
            for (int i = 0; i < originalPath.length; i++) {
                originalPath[i] = "";
            }
        } else {
            String tempOriginalPath = originalPath[arrIndex - 1];

            originalPath[arrIndex - 1] = "following" + originalPath[arrIndex].substring(originalPath[arrIndex].indexOf("::")) + "[descendant" + originalPath[arrIndex - 1].substring(originalPath[arrIndex - 1].indexOf("::")) + "]/";

            for (int i = arrIndex + 1; i < originalPath.length; i++) {
                originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + originalPath[i] + "/";
            }

            originalPath[arrIndex - 1] = originalPath[arrIndex - 1].substring(0, originalPath[arrIndex - 1].length() - 1);
            originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + "|";

            originalPath[arrIndex] = "/ancestor-or-self::*[following-sibling::*/descendant-or-self" + tempOriginalPath.substring(tempOriginalPath.indexOf("::")) + "]/" + originalPath[arrIndex];

            for (int i = arrIndex - 2; i > 0; i--) {
                originalPath[arrIndex] = "/" + originalPath[i] + originalPath[arrIndex];
            }

            // originalPath[arrIndex-2]=originalPath[arrIndex-2]+originalPath[arrIndex-1];
            // originalPath[arrIndex-1]="";
            if (originalPath[arrIndex].indexOf("/") == 0) {
                originalPath[arrIndex] = originalPath[arrIndex].substring(1, originalPath[arrIndex].length());
            }
        }
    }

    String mergeString(String[] modifiedPath) {
        String finalPath = "/";
        for (int i = 1; i < modifiedPath.length; i++) {
            finalPath = finalPath + modifiedPath[i];
            if (modifiedPath[i].length() > 0 && i < modifiedPath.length - 1) {
                finalPath = finalPath + "/";
            }
        }
        if (finalPath.length() == 1) {
            finalPath = "";
        }
        return finalPath;
    }

    String splitAncestorOrSelf(String originalPath) {
        String finalPath = "";

        if (originalPath.indexOf("/ancestor-or-self::") > 0) {
            finalPath = originalPath.substring(0, originalPath.indexOf("/ancestor-or-self::")) + "/ancestor::" + originalPath.substring(originalPath.indexOf("/ancestor-or-self::") + 19);
            finalPath = finalPath + "|" + originalPath.substring(0, originalPath.indexOf("/ancestor-or-self::")) + "/self::" + originalPath.substring(originalPath.indexOf("/ancestor-or-self::") + 19);
        } else {
            finalPath = originalPath;
        }

        return finalPath;
    }

    String symmetryPath(String originalPath) {
        String finalPath = "";
        String[] unionPathArr = originalPath.split("\\|");

        for (int i = 0; i < unionPathArr.length; i++) {

            if (unionPathArr[i].indexOf("/ancestor::") > 0) {
                String[] stepsArr = unionPathArr[i].split("/");
                int k = 1;
                while (k < stepsArr.length && stepsArr[k].indexOf("ancestor::") != 0) {
                    k++;
                }

                if (stepsArr[k - 1].indexOf("self::") == 0) {
                    ProcessSelfAncestor(stepsArr, k);
                    unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
                } else if (stepsArr[k - 1].indexOf("following-sibling::") == 0) {
                    ProcessFollowingSiblingAncestor(stepsArr, k);
                    unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
                } else if (stepsArr[k - 1].indexOf("descendant::") == 0) {
                    ProcessDescendantAncestor(stepsArr, k);
                    unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
                } else if (stepsArr[k - 1].indexOf("following::") == 0) {
                    ProcessFollowingAncestor(stepsArr, k);
                    unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
                } else {
                    ProcessChildAncestor(stepsArr, k);
                    unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
                }

                if (unionPathArr[i].indexOf("/ancestor::") > 0) {
                    unionPathArr[i] = symmetryPath(unionPathArr[i]);
                }
            }
        }

        for (int i = 0; i < unionPathArr.length; i++) {
            finalPath = finalPath + "|" + unionPathArr[i];
        }
        finalPath = finalPath.substring(finalPath.indexOf("/"));
        return finalPath;
    }
    // added by Wang Geng, Following code is used to generate CPathId for
    // Sandeep's algo

    void generateCPath() {
        try {
            Statement statement = _dbConnection.createStatement();
            Statement statement2 = _dbConnection.createStatement();
            Statement statement3 = _dbConnection.createStatement();
            String sqlquery;
            sqlquery = "SELECT PathExp,PathId FROM Path WHERE CPathId=0 ORDER BY PathId";
            ResultSet results = statement.executeQuery(sqlquery);
            int count = 0;
            String[] partsTemp;
            String TempNameTest;
            int maxLeafNum = 0;
            String maxLeafNode = ".#";
            while (true) {

                while (results.next()) {

                    partsTemp = results.getString("PathExp").split("\\.");
                    TempNameTest = "." + partsTemp[partsTemp.length - 1].trim();
                    System.out.println("@@@@@@**** test **** : PathExp=" + results.getString("PathExp"));
                    System.out.println("@@@@@@**** test **** : TempNameTest=" + TempNameTest);
                    System.out.println("@@@@@@**** test **** : maxLeafNode=" + maxLeafNode);
                    if (TempNameTest.compareTo(maxLeafNode) != 0) {
                        sqlquery = "SELECT Count(*) as CPathNum FROM Path WHERE PathExp LIKE '%" + TempNameTest.trim() + " %'";
                        ResultSet Results2 = statement2.executeQuery(sqlquery);
                        Results2.next();
                        System.out.println("@@@@@@**** test **** : count=" + Results2.getString("CPathNum"));
                        if (maxLeafNum < Results2.getInt("CPathNum")) {
                            maxLeafNum = Results2.getInt("CPathNum");
                            maxLeafNode = TempNameTest;
                        }
                    }
                }

                if (maxLeafNum != 0) {
                    sqlquery = "SELECT PathId FROM Path WHERE PathExp LIKE '%" + maxLeafNode + " %' ORDER BY PathId";
                    ResultSet Results3 = statement2.executeQuery(sqlquery);

                    int i = 1 + count;
                    while (Results3.next()) {
                        sqlquery = "UPDATE Path SET CPathId=" + i + " WHERE PathId=" + Results3.getString("PathId");
                        statement3.execute(sqlquery);
                        i++;
                    }
                    count = count + maxLeafNum;
                    maxLeafNum = 0;
                } else {
                    break;
                }
                sqlquery = "SELECT PathExp,PathId FROM Path WHERE CPathId=0 ORDER BY PathId";
                results = statement.executeQuery(sqlquery);
            }
        } catch (Exception ex) {
        }
    }
}